<template>
  <div class="am-time-container">
    <chart-header title="星座图" name="constellationPlot">
      <template #tool>
        <el-select v-model="viewType" placeholder="请选择" size="small">
          <el-option
            v-for="option in vectorOptions"
            :key="option.label"
            :label="option.label"
            :value="option.value"
          />
        </el-select>
      </template>
    </chart-header>
    <div id="constellationPlot" />
  </div>
</template>

<script setup>
  // 星座图
  import Highcharts from '@/plugins/highcharts'
  import useChartsStore from '@/store/modules/charts'
  import ChartHeader from '@/views/analyse/header/ChartHeader'
  import Interval from '@/common/classes/interval'
  import useDmFormStore from '@/store/modules/form/dmForm'
  import useChartOptions from '@/common/hooks/chartOptions'
  import ci from '@/common/chartInstances'
  import { waveSinP } from '@/utils/utils'
  import { EYE_DOT } from '@/constant'
  import { cloneDeep } from 'lodash'

  const props = defineProps({
    data: {
      type: Array,
      default: () => []
    }
  })
  const chartsStore = useChartsStore()
  const chartData = ref([]) // { lines: [], dots: [] }
  const viewType = ref('vectorAndDot')
  const vectorOptions = [
    { label: '矢量和矢量点', value: 'vectorAndDot' },
    { label: '只显示矢量', value: 'vectorOnly' },
    { label: '只显示矢量点', value: 'dotOnly' }
  ]
  const { themeStyle, chartOptions } = useChartOptions()
  const isStatic = chartsStore.static.enabled
  let instance = null
  let interval = null

  watch(
    () => themeStyle.value,
    () => {
      instance.update(genearteChartsOptions(), true)
      updateChart()
    }
  )
  watch(
    () => viewType.value,
    val => {
      for (let i = 0; i < instance.series.length; i++) {
        const s = instance.series[i]
        s.remove()
        i--
      }
      instance.update({ series: generateSeriesOption(val) }, false, true)
      updateChart()
    }
  )

  const initCharts = () => {
    const options = genearteChartsOptions()
    instance = new Highcharts.Chart('constellationPlot', options)
    ci.set(instance, 'constellationPlot')
  }
  const init = () => {
    if (interval && !interval.destroyed) {
      interval.destroy()
    }
    let temp = []
    let dotsTemp = []
    let resultLen
    const len = props.data.length
    if (isStatic) {
      const staticNum = chartsStore.static.dmLimit
      resultLen = len > staticNum ? staticNum : len
    } else {
      resultLen = useDmFormStore().resultLen
    }
    for (let i = 0; i < len; i += 2) {
      const item = [props.data[i], props.data[i + 1]]
      dotsTemp.push(item)
      // handleChartData(item, temp)
      temp.push(item)
      if ((i + 2) % (resultLen * 2) === 0 && i > 0) {
        chartData.value.push({
          dots: dotsTemp,
          line: temp
        })
        temp = []
        dotsTemp = []
      } else if (i + 2 >= len) {
        chartData.value.push({
          dots: dotsTemp,
          line: temp
        })
      }
    }
  }
  const renderView = () => {
    if (!isStatic) {
      interval = Interval.create(updateChart, 1, 0, chartData.value.length)
    }
    updateChart()
  }
  const generateSeriesOption = (type, d1 = [], d2 = []) => {
    const line = {
      type: 'spline',
      marker: {
        enabled: false
      },
      enableMouseTracking: false,
      animation: false,
      lineWidth: 0.5,
      color: themeStyle.value.lineColor,
      data: d1
    }
    const scatter = {
      type: 'scatter',
      enableMouseTracking: false,
      animation: false,
      marker: {
        enabled: true,
        fillColor: themeStyle.value.dotColor,
        radius: 2
      },
      data: d2
    }
    const result = []
    if (type === 'dotOnly') {
      result.push(scatter)
    } else if (type === 'vectorOnly') {
      result.push(line)
    } else {
      result.push(scatter)
      result.push(line)
    }
    return result
  }
  const genearteChartsOptions = () => {
    const currentOptions = cloneDeep(chartOptions.value)
    currentOptions.yAxis.min = -1
    currentOptions.yAxis.max = 1
    currentOptions.xAxis.min = -2
    currentOptions.xAxis.max = 2
    currentOptions.series = generateSeriesOption()
    return currentOptions
  }
  const handleChartData = ([x, y], temp) => {
    const last = temp.pop()
    if (!last) {
      temp.push([x, y])
      return
    }
    const [x1, y1] = last
    if (Math.abs(x - x1) > Math.abs(y - y1)) {
      waveSinP([y1, y], EYE_DOT.midDotsNum).forEach((item, index) => {
        const partNum = EYE_DOT.midDotsNum + 1
        temp.push([x1 + ((x - x1) / partNum) * index, item])
      })
    } else {
      waveSinP([x1, x], EYE_DOT.midDotsNum).forEach((item, index) => {
        const partNum = EYE_DOT.midDotsNum + 1
        temp.push([item, y1 + ((y - y1) / partNum) * index])
      })
    }
  }
  // 更新图表
  const updateChart = (start = 0) => {
    const current = chartData.value[start]
    if (!current || !instance?.series) {
      return
    }
    instance.series.forEach(s => {
      if (s.type === 'scatter') {
        s.setData(current.dots, true, false, false)
      } else {
        s.setData(current.line, true, false, false)
      }
    })
  }

  onMounted(() => {
    init()
    initCharts()
    renderView()
  })

  onUnmounted(() => {
    Interval.remove(interval)
  })
</script>
